﻿using System;
using System.Collections.Generic;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using PSIEpics;
using jtext_EpicsClient;
using JtextEpicsInterface;
using System.Text.RegularExpressions;
using string_short;


//JEClient Test
//only a demo shows how to use JEClient,you should be familiar with EpicsSharp before dig into this
//with strign get/set and monitor
//note there is little error tolerance on input so take care to input
namespace jeclient_test
{
    public partial class Form1 : Form
    {
        JECLient myClient;
        string GpvName; //global varible used in monitor
        string GpvVal; //global varible used in monitor
        ArrayList DeviceList;   //holds multiple devices

        Hashtable ValueTable;   //contain all values that is monitoring ,is used to refresh the UI.
        public Form1()
        {
            InitializeComponent();
            myClient = new JECLient();
            DeviceList = new ArrayList();
            ValueTable = new Hashtable();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //add clicked
            //use ExtType to get more from a recor 
            //like alarm time and etc..
            //there is a bug in EpicsSharp that you have to use <string> or else you get wrong value
            myClient.AddChannel<ExtTimeType<string>>(textBox1.Text);
            listBox1.Items.Add(textBox1.Text);
        }

        private void button2_Click(object sender, EventArgs e)
        {
            //set clicked
            //you can use the line below to get double out of a string
            //double a = Convert.ToDouble(myClient[listBox1.Text].Get());
            //double b = (double)a;
            //textBox2.Text = ((Double)myClient[listBox1.Text].Get()).ToString();
           
            //textBox4.Text = myClient[listBox1.Text].Get<string>();
            textBox4.Text = myClient.RecordVAL[listBox1.Text].ToString();
            
        }

        private void button3_Click(object sender, EventArgs e)
        {
            //get string clickd
            textBox4.Text = myClient.GetString(listBox1.Text);
            
        }

        private void button4_Click(object sender, EventArgs e)
        {
            //Get Byte  clicked
            //caution!!!
            //you have to use undefined channel type todo this
            byte[] sb = myClient.GetByte(listBox1.Text, Convert .ToInt16( textBox3.Text));
            textBox4.Text = "";
            textBox4.Text= Str_Short.BytesToHexString(sb,";");

        }

        private void textBox3_TextChanged(object sender, EventArgs e)
        {

        }

        private void BAddMornitor_Click(object sender, EventArgs e)
        {

            string TpvName = listBox1.Text;
            Lmonitor.Items.Add(TpvName);    //add  pv that you are monitoring to hte list view
            //add monitor to records
            myClient[TpvName].MonitorMask = MonitorMask.ALL;
            //use <ExtTimeType<string>> to do monitor job and do convert later,or you may get wrong value
            ((EpicsChannel<ExtTimeType<string>>)myClient[TpvName]).MonitorChanged += new EpicsDelegate<ExtTimeType<string >>(monitor);
            try
            {
                ValueTable.Add(TpvName, "");
            }
            catch
            { }
            

        }

        #region Monitor Event handler

        //private delegate void DisplayHandler(IAsyncResult asyncResult);

        private void monitor(EpicsChannel sender, object newValue)
        {
            //since the monitor happens in another thread so you can not handle the UI
            //so you have to use this.invoke to get the UI thread update the ui
            ExtTimeType<string> Trecod;
            Trecod= (ExtTimeType<string>)newValue;
            ValueTable[sender.ChannelName] = Trecod.Value.ToString();
            //GpvName = sender.ChannelName;
            //GpvVal = Trecod.Value.ToString();
            MethodInvoker UI_fresh = new MethodInvoker(Invoke_Display);
            this.Invoke(UI_fresh);



        }

        private void Invoke_Display()
        {

            Lmonitor.Items.Clear();
            foreach (DictionaryEntry Val in ValueTable)
            {
                Lmonitor.Items.Add(Val.Key.ToString() + " = " + Val.Value.ToString());
            }
            
            //textBox1.Text = Tval;
           

        }


        #endregion

        private void Lmonitor_SelectedIndexChanged(object sender, EventArgs e)
        {

        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        private void BTaddDevice_Click(object sender, EventArgs e)
        {
            JEDevice TDevice = JEDevice.RetrieveDevice(TBdeviceName.Text);
            TDevice.setClient();
            DeviceList.Add(TDevice);
            LSTdvicelist.Items.Add(TBdeviceName.Text);
        }

        private void LSTdvicelist_DoubleClick(object sender, EventArgs e)
        {
            JEDevice tDevice;
            tDevice = ((JEDevice)DeviceList[LSTdvicelist.SelectedIndex]);
            string[] tPropS = tDevice.GetAllProperty(); //get all propertys
            
            LSTdeviceproperty.Items.Clear();
            foreach (string tProp in tPropS)
            {
                string tStr = tProp+ " = ";
                if (tDevice.GetDataType(tProp) == CommonConst.DT_BYTEARRAY || tDevice.GetDataType(tProp) == CommonConst.DT_SBYTEARRAY )
                {
                    
                    byte[] tByte = (byte[])tDevice[tProp];

                    for (int i = 0; i < tByte.Length; i++)    //Show the byte
                    {
                        tStr += string.Format("{0:X2}", tByte[i]) + "  ";
                    }

                    LSTdeviceproperty.Items.Add(tStr);
                }
                else
                {
                    tStr = tProp + " = " + (tDevice[tProp]).ToString();
                    LSTdeviceproperty.Items.Add(tStr);
                }
            }
        }

        private void LSTdvicelist_SelectedIndexChanged(object sender, EventArgs e)
        {

        }

        private void BTsetProp_Click(object sender, EventArgs e)
        {
            JEDevice tDevice;
            tDevice = ((JEDevice)DeviceList[LSTdvicelist.SelectedIndex]);
            //set the device property array and numberic is the same
            try
            {
                if (TBpropval.Text.Contains(";") == false)
                {
                    throw new System.Exception("...");
                }
                sbyte[] tBytes;
                string[] tVals = Regex.Split(TBpropval.Text, ";", RegexOptions.IgnoreCase);
                tBytes = new sbyte[tVals.Length];
                for (int i = 0; i < tVals.Length; i++)
                {
                    tBytes[i] = Convert.ToSByte( tVals[i],16);
                }
                //the above will just make asbyte[] the following line is set device property
                tDevice[TBSetPropName.Text] = tBytes;
            }
            catch
            {
                tDevice[TBSetPropName.Text] =Convert.ToDouble(TBpropval.Text);
            }
        }

        private void TBpropval_TextChanged(object sender, EventArgs e)
        {

        }

        private void button1_Click_1(object sender, EventArgs e)
        {
            myClient.RecordVAL[listBox1.Text] = Convert.ToDouble(textBox2.Text);
        }

        private void button5_Click(object sender, EventArgs e)
        {
            //set byte
            byte[] b = Str_Short.HexStringToBytes(textBox2.Text,";");
            sbyte[] sb = Str_Short.ByteToSByte(b);
            myClient.RecordVAL[listBox1.Text] = sb;
        }

        private void button6_Click(object sender, EventArgs e)
        {
            //set string
            myClient.SetString(listBox1.Text, textBox2.Text) ;
        }

        private void button7_Click(object sender, EventArgs e)
        {
            //set nint[]
            int[] tInt = Str_Short.StringToInt(textBox2.Text, ";");
            myClient.RecordVAL[listBox1.Text] = tInt;
        }

        private void button8_Click(object sender, EventArgs e)
        {
            //set double
            double[] tDoub = Str_Short.StringToDouble(textBox2.Text, ";");
            myClient.RecordVAL[listBox1.Text] = tDoub;
        }

        private void button9_Click(object sender, EventArgs e)
        {
            //get array
            Array sb = myClient.RecordVAL[listBox1.Text] as Array;
            textBox4.Text = Str_Short.ArrayToString(sb,";");
            //textBox4.Text = "";
        }

        private void button10_Click(object sender, EventArgs e)
        {
            //get byte no lenth
            sbyte[] sb =(sbyte[]) myClient.RecordVAL[listBox1.Text] ;
            byte[] b = Str_Short.SByteToByte(sb);
            textBox4.Text = Str_Short.BytesToHexString(b,";");
        }

        private void button11_Click(object sender, EventArgs e)
        {
            JEDevice tDevice;
            tDevice = ((JEDevice)DeviceList[LSTdvicelist.SelectedIndex]);
            //set the device property array and numberic is the same
            tDevice.RunCmd(TB_Cmd.Text);
        }

        private void button13_Click(object sender, EventArgs e)
        {
            string TpvName = listBox1.Text;
            myClient.DisposeChannel(TpvName);
            listBox1.Items.Remove(listBox1.Items[listBox1.SelectedIndex]);
        }

        private void button12_Click(object sender, EventArgs e)
        {
            Lmonitor.Items.Remove(Lmonitor.Items[Lmonitor.SelectedIndex]);
        }



    }
}
